from cProfile import label
import random
from os.path import exists

from django import  forms
from django.conf import settings
import logging

from web import models
from utils import encrypt
from django_redis import get_redis_connection

from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from utils.tencent.sms_email import send_email

class RegisterModelFrom(forms.ModelForm):

    # 重写 进行添加规则 校验

    # 正则表达式 RegexValidator
    mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])

    # forms.PasswordInput() 表单密文 展示
    password = forms.CharField(
        label='密码',
        min_length=8,
        max_length=64,
        error_messages={
            'min_length':'密码长度不能小于8个字符',
            'max_length':'密码长度不能大于64个字符'
        },
        widget=forms.PasswordInput())

    confirm_password = forms.CharField(
        label='重复密码',
        widget=forms.PasswordInput(),
        max_length=64,
        error_messages={
            'min_length': '重复密码长度不能小于8个字符',
            'max_length': '重复密码长度不能大于64个字符'
        },
    )

    code = forms.CharField(
        label='验证码',
        widget=forms.TextInput())

    class Meta:
        model = models.UserInfo
        fields = ['username', 'mobile_phone', 'password', 'confirm_password', 'email', 'code']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'
            field.widget.attrs['placeholder'] = '请输入%s' % (field.label,)

    def clean_username(self):
        # 钩子函数，检验用户名
        # cleaned_data 指已验证的所有字段的数据，验证是按先后顺序 在这里检验是取不到email的 ，因为没验证到
        username = self.cleaned_data['username']
        exists = models.UserInfo.objects.filter(username=username).exists()
        if exists:
            raise ValidationError('用户名已存在')  # 报错 不会执行下面的代码，cleaned_data中不会有username值
            # self.add_error('username','用户名已存在') # 验证没通过，还是会执行下面的代码
        return username

    def clen_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        exists=models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError('手机号已注册')
        return mobile_phone

    def  clean_password(self):
        pwd = self.cleaned_data['password']
        # 加密 & 返回
        return encrypt.md5(pwd)

    def clean_confirm_password(self):

        pwd = self.cleaned_data.get('password')
        confirm_password=encrypt.md5(self.cleaned_data['confirm_password'])

        if pwd !=confirm_password:
            raise ValidationError('两次密码不一致')
        return confirm_password

    def clean_email(self):
        email = self.cleaned_data['email']
        # exists = models.UserInfo.objects.filter(email=email).exists()
        # if exists:
        #     raise ValidationError('邮箱已存在')
        return email

    def clean_code(self):
        code = self.cleaned_data['code']
        email = self.cleaned_data.get('email')

        if not email:
            return code

        conn = get_redis_connection()
        redis_code = conn.get(email)
        if not redis_code:
            raise ValidationError('验证码失效或未发送，请重新发送')

        redis_str_code = redis_code.decode('utf-8')

        if code.strip()!=redis_str_code:
            raise ValidationError('验证码错误,请重新输入')

        return code


logger = logging.getLogger(__name__)

class SendSmsForm(forms.Form):

    email = forms.EmailField(label='qq邮箱',validators=[RegexValidator(r'^[1-9]\d{4,10}@qq\.com$','qq邮箱格式错误'),])

    def __init__(self,request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_email(self):
        """qq邮箱验证的钩子"""
        # email = self.cleaned_data['email']
        # email = self.request.GET.get('email')
        # print('email:%s' % email)
        email = self.cleaned_data['email']

        # 判断短信模板是否有问题
        tpl = self.request.GET.get('tpl')
        template_id = settings.TENCENT_SMS_TEMPLATE.get(tpl)
        if not template_id:
            raise ValidationError('短信模板错误')

        # 检验数据库中是否已有qq邮件
        # exists = models.UserInfo.objects.filter(email=email).exists()
        # if exists:
        #     raise ValidationError('qq邮箱已存在')

        code = random.randint(10000, 99999)


        # 发送短信
        # sms = send_sms_single(mobile_phone, template_id, [code, ])
        try:
            # 发送短信
            sms = send_email(email, code)

            if sms != 1:
                raise ValidationError("短信发送失败，{}".format(sms['errmsg']))
        except Exception as e:
            logger.error(f"发送邮件时出错: {e}")
            raise ValidationError("短信发送失败，{}".format(str(e)))

        try:
            # 验证码 写入redis（django-redis）
            conn = get_redis_connection()
            # 60秒 存在时间
            conn.set(email, code, ex=60)
        except Exception as e:
            logger.error(f"连接 Redis 时出错: {e}")
            raise ValidationError("验证码存储失败，请稍后重试")

        return email
